package com.gradumate.client.gui;

import java.util.TreeMap;
import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.visualization.client.AbstractDataTable;
import com.google.gwt.visualization.client.AbstractDataTable.ColumnType;
import com.google.gwt.visualization.client.DataTable;
import com.google.gwt.visualization.client.VisualizationUtils;
import com.google.gwt.visualization.client.visualizations.corechart.PieChart;
import com.google.gwt.visualization.client.visualizations.corechart.PieChart.PieOptions;
import com.gradumate.client.Element;
import com.gradumate.client.GraduMate;
import com.gradumate.client.service.GraduMateService;
import com.gradumate.client.service.GraduMateServiceAsync;
import com.gradumate.shared.Gebruiker;

/**
 * Gebruiker home, homepagina van elke gebruiker ander dan de student
 * 
 * @author Hugo Zonderland
 */
public class GebruikerHome {
	// AsyncService
	private GraduMateServiceAsync server = GWT.create(GraduMateService.class);

	// Logger
	private final Logger log = Logger.getLogger(GebruikerHome.class.getName());

	// Element
	private Element element = new Element();

	// Gebruiker g
	private Gebruiker gebruiker;

	// Widgets
	private FlexTable flxTable;
	private int row;
	
	// Dialogbox
	private DialogBox db;

	/**
	 * Constructor
	 */
	public GebruikerHome() {
		// Gebruiker setten
		gebruiker = GraduMate.getGebruiker();

		// Start
		init();
	}

	/**
	 * Constructor
	 * 
	 * @param Gebruiker
	 *            g
	 */
	public GebruikerHome(Gebruiker g) {
		// Gebruiker setten
		gebruiker = g;

		// Start
		init();
	}

	private void init() {
		// loading gif
		GraduMate.setLoadingImage(true);
		
		// Berichten van het scherm af
		GraduMate.clearStatusMessages();
		
		// Loading dialogbox bouwen
		constructDialogBox();
		
		if (gebruiker != null) {
			// Gebruiker setten + menu opbouwen
			// GraduMate.setGebruiker(gebruiker);

			// Juiste moduele laden
			switch (gebruiker.getType()) {
			case 2: // Afstudeer administratie
				afstudeerAdministratieHome();
				break;
			case 3: // Afstudeercommissie voorzitter
				afstudeerCommissieVoorzitterHome();
				break;
			case 4: // Afstudeercommissie lid
				afstudeerCommissieLidHome();
				break;
			case 5: // Afstudeercoordinator
				afstudeerCoordinatorHome();
				break;
			case 6: // Studieadviseur
				studieAdviseurHome();
				break;
			case 7: // Teamleider personeels zaken
				teamleiderPersoneelsZakenHome();
				break;
			default:
				break;
			}

			// Loading gif weghalen
			GraduMate.setLoadingImage(false);

			// Overige panelen weghalen.
			RootPanel.get("tabpanel").clear();
			RootPanel.get("main").add(getPageHeader());
			RootPanel.get("main").add(flxTable);
			
		} else {

			// Loading gif weghalen
			GraduMate.setLoadingImage(false);

			// Tabpanel ook schoonmaken
			RootPanel.get("tabpanel").clear();
			
			// Foutmelding toevoegen
			GraduMate.addErrorMsg("Gebruiker kon niet worden bepaald");
		}

	}

	/**
	 * Home voor afstudeeradministratie
	 */
	private void afstudeerAdministratieHome() {
		// FlexTable aanmaken
		flxTable = new FlexTable();
		row = 0;
	}

	/**
	 * Home voor afstudeercommissie voorzitter
	 */
	private void afstudeerCommissieVoorzitterHome() {

	}

	/**
	 * Home voor afstudeercommissie lid
	 */
	private void afstudeerCommissieLidHome() {
		// FlexTable aanmaken
		flxTable = new FlexTable();
		flxTable.setStyleName("datatable");
		flxTable.setCellSpacing(0);
		flxTable.setCellPadding(0);
		
		// Dialogbox tonen
		showLoadingDialogbox();
				
		// Aantal nog te behandelen verzoeken inladen
		Runnable onLoadCallbackPieStudieAdviseur = new Runnable() {
			
			public void run() {
				
				server.getKpiWaarde(Gebruiker.TYPE_AFSTUDEERCOMMISSIE_LID, new AsyncCallback<TreeMap<String, Integer>>() {
					public void onFailure(Throwable caught) {
						log.info("Service failure -> getKpiWaarde() -> " + caught.getMessage());
						GraduMate.addAsyncError();
						
						// DialogBox weghalen
						hideLoadingDialogbox();
					}

					public void onSuccess(TreeMap<String, Integer> kpiWaarden) {
						// Mag niet null zijn.
										
						if (kpiWaarden != null) {
							
							// Waarden uit de set halen
							int onbeoordeeld = kpiWaarden.get("onbeoordeeld");
							int totaal = kpiWaarden.get("totaal");
							int goedgekeurd = kpiWaarden.get("goedgekeurd");
							int afgekeurd= kpiWaarden.get("afgekeurd");
							
							// Gegevens verwerken en in de pie stoppen
							createPieChart(onbeoordeeld, totaal, goedgekeurd, afgekeurd);
						}
					}
					
					/**
					 * Maakt de pie chart aan en verwerkt de binnengekomen gegevens erin.
					 * @param int totaal aantal afstudeerverzoeken
					 * @param int onbeoordeeld aantal onbeoordeelde afstudeerverzoeken
					 */
					private void createPieChart(int onbeoordeeld, int totaal, int goedgekeurd, int afgekeurd) {
						// Pie aanmaken met datatable en options
						PieChart pie = new PieChart(createTable(onbeoordeeld, goedgekeurd, afgekeurd), createOptions("Totaal ingediende afstudeervoorstellen: " + totaal));
						
						// toevoegen aan de flxTable
						flxTable.setWidget(row, 0, element.getDataTableHeaderLabel("Overzicht afstudeervoorstellen"));
						row++;
						flxTable.setWidget(row, 0, pie);
						row++;
						
						// elementen zijn geladen, DB weghalen
						hideLoadingDialogbox();
					}
					
					/**
					 * Maakt de data tabel aan, zet de waarde erin en geeft deze terug
					 * @param int totaal aantal ingediende afstudeerverzoeken
					 * @param int onbeoordeeld aantal onbeoordeelde afstudeerverzoeken
					 * @return AbstractDataTable
					 */
					private AbstractDataTable createTable(int onbeoordeeld, int goedgekeurd, int afgekeurd) {
						// Data table aanmaken
						DataTable data = DataTable.create();
						
						// Colummen setten
						data.addColumn(ColumnType.STRING, "Status voorstel");
						data.addColumn(ColumnType.NUMBER, "Registraties");
						
						// Hoeveel rows zijn er
						data.addRows(3);
						
						// Vullen met data
						data.setValue(0, 0, "Onbeoordeeld");
						data.setValue(0, 1, onbeoordeeld);
						data.setValue(1, 0, "Goed gekeurd");
						data.setValue(1, 1, goedgekeurd);
						data.setValue(2, 0, "Afgekeurd");
						data.setValue(2, 1, afgekeurd);

						// Terug geven
						return data;
					}
				});
			}
		};
		
		// Laad de PieChart
		VisualizationUtils.loadVisualizationApi(onLoadCallbackPieStudieAdviseur, PieChart.PACKAGE);
			
	}

	/**
	 * Home voor afstudeercoordinator
	 */
	private void afstudeerCoordinatorHome() {

	}

	/**
	 * Home voor studieadviseur
	 */
	private void studieAdviseurHome() {
		
		// FlexTable aanmaken
		flxTable = new FlexTable();
		flxTable.setStyleName("datatable");
		flxTable.setCellSpacing(0);
		flxTable.setCellPadding(0);
		
		// Dialogbox tonen
		showLoadingDialogbox();
				
		// Aantal nog te behandelen verzoeken inladen
		Runnable onLoadCallbackPieStudieAdviseur = new Runnable() {
			
			public void run() {
				
				server.getKpiWaarde(Gebruiker.TYPE_STUDIE_ADVISEUR, new AsyncCallback<TreeMap<String, Integer>>() {
					public void onFailure(Throwable caught) {
						log.info("Service failure -> getKpiWaarde() -> " + caught.getMessage());
						GraduMate.addAsyncError();
						
						// DialogBox weghalen
						hideLoadingDialogbox();
					}

					public void onSuccess(TreeMap<String, Integer> kpiWaarden) {
						// Mag niet null zijn.
										
						if (kpiWaarden != null) {
							
							// Waarden uit de set halen
							int onbeoordeeld = kpiWaarden.get("onbeoordeeld");
							int totaal = kpiWaarden.get("totaal");
							int goedgekeurd = kpiWaarden.get("goedgekeurd");
							int afgekeurd= kpiWaarden.get("afgekeurd");
							
							// Gegevens verwerken en in de pie stoppen
							createPieChart(onbeoordeeld, totaal, goedgekeurd, afgekeurd);
						}
					}
					
					/**
					 * Maakt de pie chart aan en verwerkt de binnengekomen gegevens erin.
					 * @param int totaal aantal afstudeerverzoeken
					 * @param int onbeoordeeld aantal onbeoordeelde afstudeerverzoeken
					 */
					private void createPieChart(int onbeoordeeld, int totaal, int goedgekeurd, int afgekeurd) {
						// Pie aanmaken met datatable en options
						PieChart pie = new PieChart(createTable(onbeoordeeld, goedgekeurd, afgekeurd), createOptions("Totaal ingediende afstudeerverzoeken: " + totaal));
						
						// toevoegen aan de flxTable
						flxTable.setWidget(row, 0, element.getDataTableHeaderLabel("Overzicht afstudeerverzoeken"));
						row++;
						flxTable.setWidget(row, 0, pie);
						row++;
						
						// elementen zijn geladen, DB weghalen
						hideLoadingDialogbox();
					}
					
					/**
					 * Maakt de data tabel aan, zet de waarde erin en geeft deze terug
					 * @param int totaal aantal ingediende afstudeerverzoeken
					 * @param int onbeoordeeld aantal onbeoordeelde afstudeerverzoeken
					 * @return AbstractDataTable
					 */
					private AbstractDataTable createTable(int onbeoordeeld, int goedgekeurd, int afgekeurd) {
						// Data table aanmaken
						DataTable data = DataTable.create();
						
						// Colummen setten
						data.addColumn(ColumnType.STRING, "Status verzoek");
						data.addColumn(ColumnType.NUMBER, "Registraties");
						
						// Hoeveel rows zijn er
						data.addRows(3);
						
						// Vullen met data
						data.setValue(0, 0, "Onbeoordeeld");
						data.setValue(0, 1, onbeoordeeld);
						data.setValue(1, 0, "Goed gekeurd");
						data.setValue(1, 1, goedgekeurd);
						data.setValue(2, 0, "Afgekeurd");
						data.setValue(2, 1, afgekeurd);

						// Terug geven
						return data;
					}
				});
			}
		};
		
		// Laad de PieChart
		VisualizationUtils.loadVisualizationApi(onLoadCallbackPieStudieAdviseur, PieChart.PACKAGE);
	}

	/**
	 * Home voor teamleider personeels zaken
	 */
	private void teamleiderPersoneelsZakenHome() {

		// FlexTable aanmaken
		flxTable = new FlexTable();
		flxTable.setStyleName("datatable");
		flxTable.setCellSpacing(0);
		flxTable.setCellPadding(0);
		
		// Dialogbox tonen
		showLoadingDialogbox();
				
		// Aantal nog te behandelen verzoeken inladen
		Runnable onLoadCallbackPieStudieAdviseur = new Runnable() {
			
			public void run() {
				
				server.getKpiWaarde(Gebruiker.TYPE_TEAMLEIDER_PERSONEELSZAKEN, new AsyncCallback<TreeMap<String, Integer>>() {
					public void onFailure(Throwable caught) {
						log.info("Service failure -> getKpiWaarde() -> " + caught.getMessage());
						GraduMate.addAsyncError();
						
						// DialogBox weghalen
						hideLoadingDialogbox();
					}

					public void onSuccess(TreeMap<String, Integer> kpiWaarden) {
						// Mag niet null zijn.
										
						if (kpiWaarden != null) {
							
							// Waarden uit de set halen
							int totaalstudenten = kpiWaarden.get("totaalstudenten");
							int goedgekeurd = kpiWaarden.get("goedgekeurd");
							int inbehandeling = kpiWaarden.get("inbehandeling");
							
							// Gegevens verwerken en in de pie stoppen
							createPieChart(goedgekeurd, totaalstudenten, inbehandeling);
						}
					}
					
					/**
					 * Maakt de pie chart aan en verwerkt de binnengekomen gegevens erin.
					 * @param int totaal aantal afstudeerverzoeken
					 * @param int onbeoordeeld aantal onbeoordeelde afstudeerverzoeken
					 */
					private void createPieChart(int goedgekeurd, int totaalstudenten, int inbehandeling) {
						// Pie aanmaken met datatable en options
						PieChart pie = new PieChart(createTable(goedgekeurd, inbehandeling, totaalstudenten), createOptions("Totaal studenten: " + totaalstudenten));	
						
						// toevoegen aan de flxTable
						flxTable.setWidget(row, 0, element.getDataTableHeaderLabel("Overzicht afstuderen"));
						row++;
						flxTable.setWidget(row, 0, pie);
						row++;
						
						// elementen zijn geladen, DB weghalen
						hideLoadingDialogbox();
					}
					
					/**
					 * Maakt de data tabel aan, zet de waarde erin en geeft deze terug
					 * @param int totaal aantal ingediende afstudeerverzoeken
					 * @param int onbeoordeeld aantal onbeoordeelde afstudeerverzoeken
					 * @return AbstractDataTable
					 */
					private AbstractDataTable createTable(int goedgekeurd, int inbehandeling, int totaalstudenten) {
						// Data table aanmaken
						DataTable data = DataTable.create();
						
						// Colummen setten
						data.addColumn(ColumnType.STRING, "Status verzoek");
						data.addColumn(ColumnType.NUMBER, "Registraties");
						
						// Hoeveel rows zijn er
						data.addRows(3);
						
						// Vullen met data
						data.setValue(0, 0, "Goed gekeurd");
						data.setValue(0, 1, goedgekeurd);
						data.setValue(1, 0, "In behandeling");
						data.setValue(1, 1, inbehandeling);
						data.setValue(2, 0, "Overige");
						data.setValue(2, 1, totaalstudenten - goedgekeurd - inbehandeling);

						// Terug geven
						return data;
					}
				});
			}
		};
		
		// Laad de PieChart
		VisualizationUtils.loadVisualizationApi(onLoadCallbackPieStudieAdviseur, PieChart.PACKAGE);
		
	}

	/**
	 * Maakt het header object aan en stuurt die terug.
	 * 
	 * @return FlexTable.
	 */
	private FlexTable getPageHeader() {
		// Header Table
		FlexTable flxHeader = new FlexTable();
		flxHeader.setStyleName("datatableNoBorder");
		
		// Labels erop zetten
		flxHeader.setWidget(0, 0, element.getHeaderLabel("Home"));
		flxHeader.setWidget(1, 0, element.getLabel("Hallo " + gebruiker.getVoornaam() + "!"));
		
		// Terug gven
		return flxHeader;
	}
	
	/**
	 * Geeft de opmaak van de pie terug
	 * @return
	 */
	static private PieOptions createOptions(String title) {
		PieOptions options = PieOptions.create();
		options.setWidth(500);
		options.setHeight(240);
		options.set3D(true);
		options.setTitle(title);

		return options;
	}
	
	/**
	 * Maakt de loading dialogbox aan.
	 */
	private void constructDialogBox() {
		// Dialogbox aanmaken
		db = new DialogBox();
		db.setAnimationEnabled(true);
		db.setAutoHideEnabled(false);
		db.setGlassEnabled(true);
		db.center();
		db.setGlassStyleName("glaseffect");
		
		// Inhoud van de dialogbox
		FlexTable flxDb = new FlexTable();
		flxDb.setWidget(0, 0, element.getLabel("Laden.."));
		flxDb.setWidget(0, 1, element.getLoadingGif());
		
		// Elementen in de Dialogbox droppen & tonen
		db.add(flxDb);
	}
	
	/**
	 * Laat de loading dialogbox zien
	 */
	private void showLoadingDialogbox() {
		db.show();
	}
	
	/**
	 * Verbergt de loading dialogbox
	 */
	private void hideLoadingDialogbox() {
		db.hide();
	}
}
